
#include "branchs.h"
#include <cstdlib>

Grey_Image* getNeighbourvalue(Binary_Image* img,Grey_Image* out){
    Grey_Image* neighbourvalue = MOperator::neighbourvalue(img);

    for(unsigned int i=0;i<neighbourvalue->getWidth();i++)
        for(unsigned int j=0;j<neighbourvalue->getHeight();j++){
            if(img->getPixel(i,j)==false)
                neighbourvalue->setPixel(i,j,0);
            else
                if(neighbourvalue->getPixel(i,j)>3){
                    neighbourvalue->setPixel(i,j,3);
                }
        }

    if(out==NULL)
        return neighbourvalue;
    else{
        for(unsigned int k=0;k<out->getHeight();k++)
            for(unsigned int l=0;l<out->getWidth();l++)
                out->pixelmap[k][l]=neighbourvalue->pixelmap[k][l];
        delete neighbourvalue;
        return out;
        }
}

BranchLabellingOptions::BranchLabellingOptions(){
    critical_distance=10;
    superposition_threshold_direct=0.7;
    superposition_threshold_opposite=-0.7;
    acute_threshold=0;
    opposite_threshold=-0.7;
    stabilitycondition=5;
}

//Marcel's Branchlabelling is the same as Jorge's BranchesRegionGrowing
//It should be renamed for the sake of the overall coherence
//Also this is one of the most important functions in the system, so you'd rather to put it somewhere else, instead on 'miscellaneous'
Grey_Image* branchlabelling(Position primaryseed,Grey_Image* neighbourvalue,PositionMap *crossmap,RCData* rcdata,RCData* newrcdata,BranchLabellingOptions options,unsigned int firstlabel,Grey_Image* out,unsigned int* lastlabel){

    // JORGE's comment
    // Presumably a good distance between two CR's that are not from a SUPERPOSITION
    const int CRITICALDIST=options.critical_distance;

    unsigned int label=firstlabel;

    //Jorge's comment
    //Creating a 1d 8 sized array of pointers to positions for the neighborhood
    Position* neighbours = createNeighbours();

    /*create image which has labelled branchEs*/
    Grey_Image* labelled;
    if(out==NULL)
        labelled = new Grey_Image(neighbourvalue->getHeight(),neighbourvalue->getWidth(),65500);
    else
        labelled=out;

    //Labelling connected foreground regions
 //   Binary_Image* background = (Binary_Image*)neighbourvalue->convert(Image::BINARY,0,0);
//    Grey_Image* regions = MOperator::labelling4conex(background,NULL);
//    delete background;

    // JORGE's comment: Queue of secondary seeds
    queue<Position> seedqueue;
    seedqueue.push(primaryseed);

    // JORGE's comment: Creating and initalizing stack for object pixels to be labeled along current branch
    stack<Position> tolabelling;

    /*temp lists*/
    list<Position> auxilia;/* act as queue*/
    list<Position> auxilia2;

    // JORGE's comment: vectors terminations
    list<Position> vectorsextremities;
    // JORGE's comment: vectors origins
    list<Position> vectorsbegins;

    list<Vector> vectors;

    //JORGE's comment: dot products results
    list<float> dotprod;
    list<float> dotprodsp;

    list<Position> critics;
    list<Position> criticsinbranch;

    bool regionoutward=true;


    // JORGE's comment: While there is some secondary seed enqueued, that is,
    // Until there are no more branches stemming from a branch within the tree 'rooted' at the current source seed
    while(!seedqueue.empty()){
        // JORGE's comment
        // Tracking start by pushing seed onto the stack: REGION GROWING algorithm adaptation
        tolabelling.push(seedqueue.front());

        // JORGE's comment
        // Pop the current pixel from the stack
        seedqueue.pop();

        // JORGE's comment
        // Reinitializing auxiliary variables to retrieve the last wagon
        // valid pixel "address"
        int kcurr=0, kpen=1;

        // JORGE's comment
        // Just to count the length between two CR's that may be a SUPERPOSITION
        int count=0;

        // JORGE's comment
        // True if there is an outcoming acute vector from a CR
        bool acute=false;

        Position maybeseed;
        Position maybepointer;

        Vector v0aux;
        Vector v0;
        Vector lastacute;

        Position wagon1, wagon2,wagon3,wagon_tail;
        Position current_pixel;

        bool maybesuperposition=false;

        bool findtermination=false;

        // JORGE's comment: until the stack does not become empty
        // Until the stack do not run out of current branch pixels
        while(!tolabelling.empty()){
             // JORGE's comment
            // Pop the current pixel from the stack
            current_pixel=tolabelling.top();
            tolabelling.pop();


            // JORGE's comment
            // Pointers to the lagged pixels should be updated.
            // Keeping track of the last wagon pixel address
            if(kcurr-kpen<0){
                //JORGE's comment: All pointers point to source
                wagon1 = current_pixel;
                wagon2 = current_pixel;
                wagon3 = current_pixel;
                wagon_tail = current_pixel;
                regionoutward=true;
            }else if(kcurr-kpen==0){
                //JORGE's comment: Current one pixel ahead of source
                wagon1 = current_pixel;
                wagon2 = current_pixel;
                wagon3 = current_pixel;
                regionoutward=false;
            }else if(kcurr-kpen==1){
                //JORGE's comment: Current two pixels ahead of source
                wagon1 = current_pixel;
                wagon2 = current_pixel;
            }else if(kcurr-kpen==2){
                // JORGE's comment: Current four pixels ahead of source
                // Keep this distance from Current, until touching a crossing region
                wagon_tail = wagon3;
                wagon3 = wagon2;
                wagon2 = wagon1;
                wagon1 = current_pixel;
                kpen++;
            }

            if(labelled->getPixel(current_pixel)<3){
                // JORGE's comment: Current pixel has passed the test, so label it in the branch
                if(labelled->getPixel(current_pixel)==1)
                    findtermination=true;
                if(labelled->getPixel(current_pixel)!=0)
                    labelled->setPixel(current_pixel,label);



                // JORGE's comment: The current pixel has moved one position ahead
                kcurr++;

                for(int p=0;p<8;p++){
                    if(regionoutward){
                        if(labelled->getPixel(current_pixel+neighbours[p])<3&&labelled->getPixel(current_pixel+neighbours[p])>0){
                            tolabelling.push(current_pixel+neighbours[p]);
                            break;
                        }
                    }
                    else
                        if(labelled->getPixel(current_pixel+neighbours[p])<6&&labelled->getPixel(current_pixel+neighbours[p])>0){
                            tolabelling.push(current_pixel+neighbours[p]);
                            break;
                        }
                }

                // JORGE's comment
                // Testing whether we're getting out a critical region with
                // an acute outcoming vector, moreover whether there's a too close CR
                // nearby, probably due to a SUPERPOSITION
                if(acute){
                    if(count<CRITICALDIST){
                        maybesuperposition=true;
                        critics.push_back(current_pixel);
                        count++;
                    }
                    else{
                        maybesuperposition=false;
                        seedqueue.push(maybeseed);
                        critics.clear();
                        acute=false;
                    }
                }

            }
            else if(labelled->getPixel(current_pixel)<5){

                //if already rotuled as crossig
                bool alreadycross=false;

                if(labelled->getPixel(current_pixel)==4)
                    alreadycross=true;

                /*auxiliar iterators*/
                list<Position>::iterator itr,itr2;
                list<Vector>::iterator vec_itr,vec_itr2;

                CriticalRegion criticalregion = CriticalRegion();
                CriticalRegion::RegionType forcedtype = rcdata->getforcedclassification(current_pixel);

                if(forcedtype!=CriticalRegion::NONE)
                    cout << "yes must be forced\n!!!" << "current pixel: " << current_pixel.x << "," << current_pixel.y << "\n";


                /*Find incoming and outcoming vector and dot products*/
                {


                    unsigned int criticallabel=labelled->getPixel(current_pixel);


                    bool dejaread;

                    /*counters*/
                    int counter=0;
                    int pixelcounter1=0,pixelcounter2=0;

                    /*labelling first critical points*/
                    auxilia2.push_back(current_pixel);/*push in list already read pixels*/
                    critics.push_back(current_pixel);


                    for(int p=0;p<8;p++){
                        /*search critical points in neighbour*/
                        if(labelled->getPixel(current_pixel+neighbours[p])<6&&labelled->getPixel(current_pixel+neighbours[p])>0){
                                auxilia.push_back(current_pixel+neighbours[p]);
                                pixelcounter2++;
                        }

                    }


                    /*stability adjust*/
                       for(itr=auxilia.begin();itr!=auxilia.end();itr++){
                           if(labelled->getPixel(*itr)==3||labelled->getPixel(*itr)==4){
                                counter=0;
                                labelled->setPixel(*itr,criticallabel);
                                critics.push_back(*itr);
                           }
                           else
                                if(labelled->getPixel(*itr)<3){
                                    labelled->setPixel(*itr,5);
                                    criticsinbranch.push_back(*itr);
                                }
                       }
                       counter++;

                    /*Breadth-Width Search*/ /*begin: */
                    while(counter<options.stabilitycondition){


                       pixelcounter1=pixelcounter2;
                       pixelcounter2=0;

                       /*push in list already read pixels*/
                       for(itr=auxilia.begin();itr!=auxilia.end();itr++)
                            auxilia2.push_back(*itr);

                       /*for current critical points*/
                       /*find new neighbours*/
                       /*add news that aren't already read and already are on queue*/
                       for(int j=0;j<pixelcounter1;j++){
                            for(int p=0;p<8;p++){
                                dejaread=false;
                                if(labelled->getPixel(auxilia.front()+neighbours[p])>0&&labelled->getPixel(auxilia.front()+neighbours[p])<6){
                                    for(itr2=auxilia2.begin();itr2!=auxilia2.end();itr2++)
                                        if(auxilia.front()+neighbours[p]==*itr2)
                                            dejaread=true;
                                    for(itr=auxilia.begin();itr!=auxilia.end();itr++)
                                        if(auxilia.front()+neighbours[p]==*itr)
                                            dejaread=true;
                                    if(dejaread==false){
                                        auxilia.push_back(auxilia.front()+neighbours[p]);
                                        pixelcounter2++;
                                    }
                                }

                            }
                            if(!auxilia.empty()){
                                auxilia.pop_front();/*erase current pixels from queue*/
                            }
                       }

                       /*stability adjust*/
                       for(itr=auxilia.begin();itr!=auxilia.end();itr++){
                           if(labelled->getPixel(*itr)==3||labelled->getPixel(*itr)==4){
                                counter=0;
                                labelled->setPixel(*itr,criticallabel);
                                critics.push_back(*itr);
                           }
                           else
                                if(labelled->getPixel(*itr)<3){
                                    labelled->setPixel(*itr,5);
                                    criticsinbranch.push_back(*itr);
                                }
                       }
                       counter++;



                    }
                    /*non critical in rest are extremities from emergent vectors, put these in the list*/
                    for(itr=auxilia.begin();itr!=auxilia.end();itr++){
                        if(neighbourvalue->getPixel(*itr)<3){
                            vectorsextremities.push_back(*itr);
                        }
                    }

                    /*branch-width search*/ /*end: */

                    /*find vectors begin put these in the list*/
                    for(itr=vectorsextremities.begin();itr!=vectorsextremities.end();itr++){
                        Position nextpixel;
                        Position last;
                        Position anterior;
                        nextpixel=*itr;

                        /*first iteration put tracking in correct direction*/
                        anterior=*itr;
                        last=nextpixel;
                        for(int p=0;p<8;p++){
                            if(labelled->getPixel(last+neighbours[p])==5){
                                 nextpixel=(last+neighbours[p]);
                                 break;
                            }
                        }
                        labelled->setPixel(last,2);
                        criticsinbranch.remove(last);


                        /*next iterations*/
                        while(neighbourvalue->getPixel(nextpixel)!=3&&neighbourvalue->getPixel(nextpixel)!=4){
                            bool exit=false;
                            anterior=last;
                            last=nextpixel;
                            for(int p=0;p<8;p++){
                                if(labelled->getPixel(last+neighbours[p])>2){
                                    if(neighbourvalue->getPixel(last+neighbours[p])==3||neighbourvalue->getPixel(last+neighbours[p])==4){
                                        nextpixel=(last+neighbours[p]);
                                        exit=true;
                                    }
                                    else
                                        if(last+neighbours[p]!=anterior)
                                            nextpixel=(last+neighbours[p]);
                                }
                                labelled->setPixel(last,2);
                                criticsinbranch.remove(last);
                                if(exit)
                                    break;
                            }
                        }
                        vectorsbegins.push_back(last);

                    }

                    /*Do list of emergent normalized outcoming vectors*/
                    itr=vectorsextremities.begin();
                    itr2=vectorsbegins.begin();
                    while(itr!=vectorsextremities.end()){
                        Vector temp;
                        temp = pointfromposition(*itr)-pointfromposition(*itr2);
                        vectors.push_back(temp);
                        itr++;itr2++;
                    }

                    /*get incoming vector*/
                    v0 = pointfromposition(wagon1)-pointfromposition(wagon_tail);
                    v0.normalize();

                    /*create a list of dot products*/
                    for(vec_itr=vectors.begin();vec_itr!=vectors.end();vec_itr++){
                        float prod;
                        (*vec_itr).normalize();
                        prod=(*vec_itr)*v0;
                        dotprod.push_back(prod);
                    }

                    if(maybesuperposition){
                        for(vec_itr=vectors.begin();vec_itr!=vectors.end();vec_itr++){
                            float prod;
                            (*vec_itr).normalize();
                            prod=(*vec_itr)*v0aux;
                            dotprodsp.push_back(prod);
                        }
                    }
                }
                /*Critical region classification and treatment*/
                {
                    if(vectors.size()==2){

                        if(maybesuperposition){

                            /*Bigger dot product defines next labelled*/
                            bool choosefront;
                            bool issuperposition=false;
                            maybesuperposition=false;

                            if(dotprodsp.front()>dotprodsp.back())
                                choosefront=true;
                            else
                                choosefront=false;

                            if(choosefront){
                                if(dotprodsp.front()>options.superposition_threshold_direct || forcedtype==CriticalRegion::SUPERPOSITION)
                                    if( (lastacute*vectors.back())< options.superposition_threshold_opposite || forcedtype==CriticalRegion::SUPERPOSITION)
                                        issuperposition=true;
                            }
                            else{
                                if(dotprodsp.back()>options.superposition_threshold_direct || forcedtype==CriticalRegion::SUPERPOSITION)
                                    if( (lastacute*vectors.front())< options.superposition_threshold_opposite || forcedtype==CriticalRegion::SUPERPOSITION )
                                        issuperposition=true;
                            }

                            if(issuperposition){
                                std::cout<<"superposition\n";

                                criticalregion.set_emergent_vec(3);
                                criticalregion.setType(CriticalRegion::SUPERPOSITION);
                                criticalregion.forceType(forcedtype);

                                if(choosefront){
                                    tolabelling.push(vectorsbegins.front());
                                    if(crossmap!=NULL){
                                        crossmap->setPosition(maybepointer,vectorsbegins.front());
                                        crossmap->setPosition(vectorsbegins.front(),maybepointer);

                                        crossmap->setPosition(vectorsbegins.back(),maybeseed);
                                        crossmap->setPosition(maybeseed,vectorsbegins.back());
                                    }
                                }
                                else{
                                    tolabelling.push(vectorsbegins.back());
                                    if(crossmap!=NULL){
                                        crossmap->setPosition(maybepointer,vectorsbegins.back());
                                        crossmap->setPosition(vectorsbegins.back(),maybepointer);

                                        crossmap->setPosition(vectorsbegins.front(),maybeseed);
                                        crossmap->setPosition(maybeseed,vectorsbegins.front());
                                    }
                                }
                                while(!critics.empty()){
                                    labelled->setPixel(critics.back(),4);
                                    criticalregion.addPoint(critics.back());
                                    critics.pop_back();
                                }
                                acute=false;
                                kcurr=0;kpen=1;
                            }
                            else{

                                criticalregion.set_emergent_vec(2);
                                criticalregion.setType(CriticalRegion::BIFURCATION);
                                criticalregion.forceType(forcedtype);

                                seedqueue.push(maybeseed);
                                acute=false;

                                if(dotprod.front()>dotprod.back())
                                    choosefront=true;
                                else
                                    choosefront=false;

                                if(choosefront){
                                    tolabelling.push(vectorsbegins.front());
                                    if(dotprod.back()<options.acute_threshold){
                                        acute=true;
                                        maybeseed=vectorsbegins.back();
                                        maybepointer=wagon2;
                                        lastacute=vectors.back();
                                        kcurr=0;kpen=1;
                                    }
                                    else{
                                        seedqueue.push(vectorsbegins.back());
                                        kcurr=0;kpen=1;
                                        acute=false;
                                        for(itr2=critics.begin();itr2!=critics.end();itr2++){
                                            criticalregion.addPoint(*itr2);
                                        }
                                        critics.clear();
                                    }
                                }
                                else{
                                    tolabelling.push(vectorsbegins.back());
                                    if(dotprod.front()<options.acute_threshold){
                                        acute=true;
                                        maybeseed=vectorsbegins.front();
                                        maybepointer=wagon2;
                                        lastacute=vectors.front();
                                        kcurr=0;kpen=1;
                                    }
                                    else{
                                        seedqueue.push(vectorsbegins.front());
                                        kcurr=0;kpen=1;
                                        acute=false;
                                        for(itr2=critics.begin();itr2!=critics.end();itr2++){
                                            criticalregion.addPoint(*itr2);
                                        }
                                        critics.clear();
                                    }
                                }
                            }

                        }
                        else{
                            criticalregion.set_emergent_vec(2);
                            criticalregion.setType(CriticalRegion::BIFURCATION);
                            criticalregion.forceType(forcedtype);

                            /*Bigger dot product defines next labelled*/
                            bool choosefront;

                            if(dotprod.front()>dotprod.back())
                                choosefront=true;
                            else
                                choosefront=false;

                            if(choosefront){
                                tolabelling.push(vectorsbegins.front());
                                if(dotprod.back()<options.acute_threshold || forcedtype==CriticalRegion::SUPERPOSITION){
                                    acute=true;
                                    maybeseed=vectorsbegins.back();
                                    maybepointer=wagon2;
                                    lastacute=vectors.back();
                                    kcurr=0;kpen=1;
                                }
                                else{
                                    seedqueue.push(vectorsbegins.back());
                                    kcurr=0;kpen=1;
                                    acute=false;
                                    for(itr2=critics.begin();itr2!=critics.end();itr2++){
                                        criticalregion.addPoint(*itr2);
                                    }
                                    critics.clear();
                                }
                            }
                            else{
                                tolabelling.push(vectorsbegins.back());
                                if(dotprod.front()<options.acute_threshold || forcedtype==CriticalRegion::SUPERPOSITION){
                                    acute=true;
                                    maybeseed=vectorsbegins.front();
                                    maybepointer=wagon2;
                                    lastacute=vectors.front();
                                    kcurr=0;kpen=1;
                                }
                                else{
                                    seedqueue.push(vectorsbegins.front());
                                    for(itr2=critics.begin();itr2!=critics.end();itr2++){
                                        criticalregion.addPoint(*itr2);
                                    }
                                    critics.clear();
                                    acute=false;
                                    kcurr=0;kpen=1;
                                }
                            }
                        }
                    }
                    else if(vectors.size()>=3){
                        /*Bigger dot product defines next labelled*/
                        Position nextrotulado;
                        float prod=0;


                        /*find bigger dot prodct*/
                        itr=vectorsbegins.begin();
                        vec_itr=vectors.begin();
                        for(list<float>::iterator itr3 = dotprod.begin();itr3!=dotprod.end();itr3++){
                           if(*itr3>prod){
                                prod=*itr3;
                                nextrotulado=*itr;
                            }
                            itr++;
                            vec_itr++;
                        }
                        tolabelling.push(nextrotulado);

                        bool hasopposite=false;

                        if(forcedtype==CriticalRegion::CROSSING)
                            hasopposite=true;
                        else{
                            /*Verify if has opposite angles*/
                            vec_itr=vectors.begin();
                            for(itr=vectorsbegins.begin();itr!=vectorsbegins.end();itr++){
                                if(*itr!=nextrotulado){
                                    for(vec_itr2=vectors.begin();vec_itr2!=vectors.end();vec_itr2++){
                                        prod=(*vec_itr)*(*vec_itr2);
                                        if(prod<=options.opposite_threshold&&forcedtype!=CriticalRegion::BIFURCATION){
                                            hasopposite=true;
                                        }
                                    }
                                }
                            }
                        }
                       /*se existirem vetores quase opostos é um cruzamento e pinta-se de 4*/
                       if(hasopposite){

                           criticalregion.set_emergent_vec(vectors.size());
                           criticalregion.setType(CriticalRegion::CROSSING);
                           criticalregion.forceType(forcedtype);


                           if(crossmap!=NULL){


                                Position one=Position(-1,-1);
                                Position two=Position(-1,-1);

                                vec_itr=vectors.begin();
                                itr=vectorsbegins.begin();
                                float biggerprod=1;
                                list<Vector>::iterator vecforerase1,vecforerase2;
                                list<Position>::iterator pointforerase1,pointforerase2;
                                while(itr!=vectorsbegins.end()){
                                    if(*itr!=nextrotulado){
                                        itr2=vectorsbegins.begin();
                                        vec_itr2=vectors.begin();
                                        while(vec_itr2!=vectors.end()){
                                            prod=(*vec_itr)*(*vec_itr2);
                                            if(prod<biggerprod){
                                                one=*itr;
                                                two=*itr2;
                                                vecforerase1=vec_itr;
                                                vecforerase2=vec_itr2;
                                                pointforerase1=itr;
                                                pointforerase2=itr2;
                                                biggerprod=prod;
                                            }
                                            vec_itr2++;
                                            itr2++;
                                        }
                                    }
                                    itr++;
                                    vec_itr++;
                                }
                                vectorsbegins.erase(pointforerase1);
                                vectorsbegins.erase(pointforerase2);

                                for(itr=vectorsbegins.begin();itr!=vectorsbegins.end();itr++)
                                    seedqueue.push(*itr);


                                cout << "Isso: " << one.x << "-" << one.y << " indica ali: " << two.x << "-" << two.y << endl;
                                crossmap->setPosition(one,two);
                                crossmap->setPosition(two,one);
                                cout << "Isso: " << wagon2.x << "-" << wagon2.y << " indica ali: " << nextrotulado.x << "-" << nextrotulado.y << endl;
                                crossmap->setPosition(wagon2,nextrotulado);
                                crossmap->setPosition(nextrotulado,wagon2);

                           }
                           while(!critics.empty()){
                                    labelled->setPixel(critics.back(),4);
                                    criticalregion.addPoint(critics.back());
                                    critics.pop_back();
                                }
                       }
                       critics.clear();
                       kcurr=0;kpen=1;
                    }
                    else if(vectors.size()==1){
                        tolabelling.push(vectorsbegins.front());
                        critics.clear();
                        kcurr=0;kpen=1;
                    }

                    v0aux=v0;

                    while(!criticsinbranch.empty()){
                        labelled->setPixel(criticsinbranch.back(),3);
                        criticalregion.addPoint(criticsinbranch.back());
                        criticsinbranch.pop_back();
                    }



                    /*clear used lists*/
                    auxilia.clear();
                    auxilia2.clear();
                    vectorsbegins.clear();
                    vectorsextremities.clear();
                    vectors.clear();
                    dotprod.clear();

                    count=0;

                }
                newrcdata->addRegion(criticalregion);
            }
            else/*just rotuled*/{findtermination=true;}

        }


        if(findtermination==false){

            neighbourvalue->setPixel(wagon2,0);
            labelled->setPixel(wagon2,0);
            neighbourvalue->setPixel(wagon3,0);
            labelled->setPixel(wagon3,0);
            neighbourvalue->setPixel(wagon_tail,0);
            labelled->setPixel(wagon_tail,0);
        }


        label++;
    }

    if(lastlabel!=NULL)
        *lastlabel=label;

    return labelled;
}


PositionMap::PositionMap(unsigned int height,unsigned int width){
    //set Grey_image propriety:
    setHeight(height);
    setWidth(width);
    setPixelSize(SIZE_NOT_DEFINED);
    setType(DATA);

    //Allocate pixelmap:
    map = new Position*[height];
    for(unsigned int i=0;i<height;i++)
        map[i]=new Position[width];
    if(map[height-1]==NULL)exit(13)/*Must be swapped by correct "out of memory" function/exception*/;

    //Zero pixmap:
    for(unsigned int i=0;i < height;i++)
        for(unsigned int j=0;j < width;j++)
            map[i][j]=Position(-1,-1);
}

PositionMap::~PositionMap(){
    for(unsigned int i=0;i < getHeight() ;i++)
        delete[] map[i];
}

void PositionMap::setPosition(Position position,Position value){
    map[position.y][position.x]=value;
}

Position PositionMap::getPosition(Position position){
    return map[position.y][position.x];
}

Position PositionMap::getPosition(int xposition,int yposition){
    return map[yposition][xposition];
}

void PositionMap::invert(){

}

Image* PositionMap::convert(ImageType newtype,int option,unsigned int value){
    return NULL;
}

void newlabelling(Binary_Image* seeds,Binary_Image* branchskel,Binary_Image* body,BranchLabellingOptions options,PositionMap *crossmap,RCData* rcdata,RCData* newrcdata,Grey_Image* labelled){

    if(crossmap==NULL) return;
    if(labelled==NULL) return;
    if(rcdata==NULL) return;
    if(newrcdata==NULL) return;


    /*Segmenting Critical Regions*/
    /*JORGE's comment: rename this function to findCriticalRegionsFromSkel*/
    Grey_Image* neighbourvalue = getNeighbourvalue(branchskel);

    //JORGE's comment:
    //Initial label; this variable should be renamed to curlabel
    unsigned int curlabel=6;


    /*Primary seeds queue*/
    queue<Position>* filasementes = seeds->getQueueofPoints();


    neighbourvalue->copy(labelled);

    while(!filasementes->empty()){
        branchlabelling(filasementes->front(),neighbourvalue,crossmap,rcdata,newrcdata,options,curlabel,labelled,&curlabel);
        filasementes->pop();
        curlabel++;
    }

    Grey_Image* bodygrey = (Grey_Image*)body->convert(Image::GREY);

    labelled->ADD(bodygrey);
    labelled->ADD(bodygrey);

    delete filasementes;
    delete neighbourvalue;
    delete bodygrey;

}

